//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Core.h".
//-------------------------------------------------------------------

#ifndef _UXS_SIGNATURE_H
#define _UXS_SIGNATURE_H

#pragma once

#include "../BaseTypes/Types.h"

namespace UX_STL
{
namespace CompileTime
{
	

	//
	// Signature
	//
	
	namespace _ctime_hidden_
	{
		template <char C, typename T, uint Index>
		struct _PackChar
		{
			enum {
				MIN_VALUE		= ' ',
				MAX_VALUE		= 'Z',
				_is_in_range	= (C >= MIN_VALUE and C <= MAX_VALUE),
				OFFSET			= 0,
				CHAR_OFFSET		= 8,
				MASK			= 0xFF,
			};

			STATIC_ASSERTE( _is_in_range );

			static const T	value = ( ( T(C) >> OFFSET ) & MASK ) << (CHAR_OFFSET * Index);
		};

	}	// _ctime_hidden_

	
	template <char C0, char C1, char C2, char C3>
	struct TSignature4
	{
		typedef TSignature4< C0, C1, C2, C3 >	Self;
		typedef uint32							value_t;

		static const value_t	value =		 value_t(C0) |
											(value_t(C1) << 8) |
											(value_t(C2) << 16) |
											(value_t(C3) << 24);
	};


	template <char C0, char C1 = ' ', char C2 = ' ', char C3 = ' ',
			  char C4 = ' ', char C5 = ' ', char C6 = ' ', char C7 = ' '
			 >
	struct TSignature8
	{
		typedef TSignature8< C0, C1, C2, C3, C4, C5, C6, C7 >	Self;
		typedef uint32											half_value_t;
		typedef uint64											value_t;

		DEBUG_ONLY(
			static const char	name[9];
		)

		static const half_value_t	value0 =	_ctime_hidden_::_PackChar< C0, half_value_t, 0 >::value |
												_ctime_hidden_::_PackChar< C1, half_value_t, 1 >::value |
												_ctime_hidden_::_PackChar< C2, half_value_t, 2 >::value |
												_ctime_hidden_::_PackChar< C3, half_value_t, 3 >::value;
		
		static const half_value_t	value1 =	_ctime_hidden_::_PackChar< C4, half_value_t, 0 >::value |
												_ctime_hidden_::_PackChar< C5, half_value_t, 1 >::value |
												_ctime_hidden_::_PackChar< C6, half_value_t, 2 >::value |
												_ctime_hidden_::_PackChar< C7, half_value_t, 3 >::value;

		static const value_t		value  =	( value_t(value1) << (sizeof(half_value_t)*8) ) | value_t(value0);
	};
	
	DEBUG_ONLY(
		template <char C0, char C1, char C2, char C3, char C4, char C5, char C6, char C7>
		const char	TSignature8< C0, C1, C2, C3, C4, C5, C6, C7 >::name[9] = { C0, C1, C2, C3, C4, C5, C6, C7, 0 };
	)


}	// CompileTime
}	// UX_STL

#endif	// _UXS_SIGNATURE_H